using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public struct Line
{
    public Vector3 From;
    public Vector3 To;
}

public class Ray
{
    public Vector3 From;
    public Vector3 Dir;
    public Color Col;
}

public class MapDrawer
{
    public List<TriangleData> Map => _mapDraw;
    public Vector3 StartPos => _startPos;
    public Vector3 EndPos => _endPos;

    //地图网格
    public bool IsDrawMap;
    private List<TriangleData> _mapDraw;
    private TriangleData _selectedTriangle;
    
    //二维网格
    public bool IsDrawArrMap;
    public List<GridData> GridDatas => _gridDatas;
    private List<GridData> _gridDatas;
    public Vector3 TerrainSize;
    public float GirdSize { get; private set; }

    //寻路
    public bool IsDrawPath;
    private Vector3 _startPos;
    private Vector3 _endPos;
    private List<Line> _pathList;
    private List<Line> _gridPathList;
    private Dictionary<string, List<Ray>> _pathRayMap;
    private List<Ray> _viewRay;
    private int _viewRayIdx;

    private static MapDrawer _instance;

    public MapDrawer()
    {
        _mapDraw = new List<TriangleData>();
        _pathList = new List<Line>();
        _gridPathList = new List<Line>();
        _pathRayMap = new Dictionary<string, List<Ray>>();
        _viewRay = new List<Ray>();
        _gridDatas = new List<GridData>();
    }

    public static MapDrawer GetInstance()
    {
        if (_instance == null)
        {
            _instance = new MapDrawer();
        }

        return _instance;
    }

    public void Clear()
    {
        ClearPath();
        _mapDraw.Clear();
        _gridDatas.Clear();
        _selectedTriangle = null;
    }

    public void AddMapTriangle(TriangleData t)
    {
        _mapDraw.Add(t);
    }

    public void SetSelectTriangle(int idx)
    {
        if (idx < 0 || idx >= _mapDraw.Count) return;
        _selectedTriangle = _mapDraw[idx];
    }

    public void CalNeighbourMap()
    {
        if (_selectedTriangle == null || _mapDraw.Count <= 0) return;
        float dis = 0.05f;
        //拷贝，用于遍历
        List<TriangleData> copyList = new List<TriangleData>();
        for (int i = 0; i < _mapDraw.Count; i++)
        {
            copyList.Add(_mapDraw[i]);
        }

        List<TriangleData> neighbourList = new List<TriangleData>();
        neighbourList.Add(_selectedTriangle);
        copyList.Remove(_selectedTriangle);

        for (int i = 0; i < neighbourList.Count; ++i)
        {
            var data1 = neighbourList[i];
            for (int j = 0; j < copyList.Count; ++j)
            {
                var data2 = copyList[j];
                if ((data1.A - data2.A).magnitude < dis ||
                    (data1.A - data2.B).magnitude < dis ||
                    (data1.A - data2.C).magnitude < dis ||
                    (data1.B - data2.A).magnitude < dis ||
                    (data1.B - data2.B).magnitude < dis ||
                    (data1.B - data2.C).magnitude < dis ||
                    (data1.C - data2.A).magnitude < dis ||
                    (data1.C - data2.B).magnitude < dis ||
                    (data1.C - data2.C).magnitude < dis)
                {
                    neighbourList.Add(copyList[j]);
                    copyList.RemoveAt(j);
                    --j;
                }
            }
        }

        // 根据Id排序
        neighbourList.Sort((x, y) => x.Id.CompareTo(y.Id));
        //重置Id
        for (int i = 0; i < neighbourList.Count; ++i)
        {
            neighbourList[i].Id = i;
        }

        _mapDraw = neighbourList;
    }

    public void SetStartPos(string str)
    {
        int x, y;
        var arr = str.Split(",");
        if (!Int32.TryParse(arr[0], out x) || !Int32.TryParse(arr[1], out y)) return;
        _startPos = new Vector3(x, 0, y);
    }

    public void SetEndPos(string str)
    {
        int x, y;
        var arr = str.Split(",");
        if (!Int32.TryParse(arr[0], out x) || !Int32.TryParse(arr[1], out y)) return;
        _endPos = new Vector3(x, 0, y);
    }

    public void SetGridSize(string str)
    {
        float size;
        if(!float.TryParse(str,out size)) return;
        GirdSize = size;
    }

    public void ClearPath()
    {
        _gridPathList.Clear();
        _pathList.Clear();
        _pathRayMap.Clear();
        _viewRay.Clear();
        _viewRayIdx = -1;
    }

    public void AddPath(Line line)
    {
        _pathList.Add(line);
    }

    public void AddGridPath(Line line)
    {
        _gridPathList.Add(line);
    }

    public void AddRay(string k, Ray ray)
    {
        if (!_pathRayMap.ContainsKey(k))
        {
            _pathRayMap[k] = new List<Ray>();
        }

        _pathRayMap[k].Add(ray);
    }

    public void PreView()
    {
        _viewRayIdx--;
        if (_viewRayIdx < 0)
        {
            _viewRayIdx = 0;
        }

        _viewRay.Clear();
        _viewRay.Add(_pathRayMap["v1"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v2"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v3"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v4"][_viewRayIdx]);

        var cross = _pathRayMap["cross"][_viewRayIdx];
        if (cross != null)
        {
            _viewRay.Add(cross);
        }
    }

    public void NextView()
    {
        _viewRayIdx++;
        if (_viewRayIdx >= _pathRayMap["v1"].Count)
        {
            _viewRayIdx = _pathRayMap["v1"].Count - 1;
        }

        _viewRay.Clear();
        _viewRay.Add(_pathRayMap["v1"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v2"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v3"][_viewRayIdx]);
        _viewRay.Add(_pathRayMap["v4"][_viewRayIdx]);
        var cross = _pathRayMap["cross"][_viewRayIdx];
        if (cross != null)
        {
            _viewRay.Add(cross);
        }
    }

    public void SetArrGridMap(List<GridData> map)
    {
        _gridDatas = map;
    }

    public void DrawAll()
    {
        //地图
        if (IsDrawMap)
        {
            for (int i = 0; i < _mapDraw.Count; i++)
            {
                _mapDraw[i].Draw(Color.green);
            }

            //选中三角形块
            if (_selectedTriangle != null)
            {
                _selectedTriangle.Draw(Color.yellow);
            }
        }

        //初始位置
        if (IsDrawPath)
        {
            Handles.color = Color.blue;
            Handles.DrawLine(_startPos, new Vector3(_startPos.x, 100, _startPos.z));
            Handles.DrawLine(_endPos, new Vector3(_endPos.x, 100, _endPos.z));
            for (int i = 0; i < _pathList.Count; i++)
            {
                Handles.DrawLine(_pathList[i].From, _pathList[i].To);
            }

            Handles.color = Color.red;
            for (int i = 0; i < _gridPathList.Count; i++)
            {
                Handles.DrawLine(_gridPathList[i].From, _gridPathList[i].To);
            }

            for (int i = 0; i < _viewRay.Count; i++)
            {
                var ray = _viewRay[i];
                Debug.DrawRay(ray.From, ray.Dir, ray.Col);
            }
        }

        if (IsDrawArrMap)
        {
            foreach (var kv in _gridDatas)
            {
                kv.Draw();
            }
        }
        
        
    }
}